package mspbots.autotask.client.core.data.contracts;


import com.fasterxml.jackson.databind.JsonNode;
import lombok.extern.log4j.Log4j2;
import mspbots.autotask.client.core.AbstractToolsUtil;
import mspbots.autotask.client.core.BaseApiService;
import mspbots.autotask.client.core.client.ClientProperties;
import mspbots.autotask.client.core.client.ClientUtils;
import mspbots.autotask.common.*;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.net.URI;
import java.time.LocalDateTime;
import java.util.UUID;

@Log4j2
@Service
public class ContractsServiceImpl extends AbstractToolsUtil implements BaseApiService {

    private final String QUERY_REQUEST_PATH = "/V1.0/Contracts/query";

    @Override
    public <T> T find(Long tenantId, QueryBody queryBody, URI pageUrl) {
        return null;
    }

    @Override
    public <T> T count(Long tenantId, QueryBody queryBody) {
        return null;
    }

    @Override
    public Mono<Void> syncSlow(ClientProperties properties) {
        return syncData8(properties).then();
    }


    public Flux<JsonNode> syncData8(ClientProperties properties) {
        ResultSync resultSync = ResultSync.withDefault("CONTRACTS-SYNC");
        return this.dateCacheFilterFetch(properties)
                .subscriberContext(ctx -> ctx.put("resultSync", resultSync))
                .doOnNext(result -> this.syncResult(properties.getTenantId(), resultSync.getRequestId(), result));
    }

    @Override
    public Mono<Void> syncInformation(ClientProperties properties) {

        ResultSync resultInfoSync = ResultSync.withDefault("CONTRACTS-ENTITY-INFORMATION");
        return this.entityInformation(properties)
                .subscriberContext(ctx -> ctx.put("resultSync", resultInfoSync))
                .doOnNext(result -> this.syncInformationResult(properties.getTenantId(),
                        resultInfoSync.getRequestId(), result))
                .then();

    }

    private Flux<JsonNode> dateCacheFilterFetch(ClientProperties properties) {
//        String redisAnchorKey = RedisKeys.TASKS_ANCHOR_REDIS_KEY_PREFIX + properties.getTenantId();
//        return super.readAnchorTime(redisAnchorKey)
//                .flatMapMany(syncTime -> this.fetch(properties, QueryBody.withFilter(FilterExpression.builder()
//                        .op("gt").field("LastActivityDateTime").value(syncTime).build())))
//                .map(result-> {
//                    log.info("tasks result:{}",result);
//                    return result;
//                })
//                .doOnNext(project -> {
//                    log.info("tasks result:{}",project);
//                    super.recordAnchorTime(redisAnchorKey, project.get("lastActivityDateTime").textValue());
//                });
        return this.fetch(properties, QueryBody.withFilter(FilterExpression.builder()
                .op("gt").field("id").value("0").build()));
    }

    private Flux<JsonNode> fetch(ClientProperties properties, QueryBody queryBody) {
        return super.autoTaskClient
                .fetch(ClientUtils.builderRequestUrl(properties.getBaseUrl(), QUERY_REQUEST_PATH), queryBody)
                .subscriberContext(ctx -> ctx.put("properties", properties));
    }

    private void syncResult(Long tenantId, UUID id, JsonNode resultNode) {
        this.sendEntity(RabbitKeys.CONTRACTS_SYNC_QUEUE_KEY, ResultMsg.builder()
                .requestId(id).id(resultNode.get("id").longValue())
                .action("none").entity(resultNode).tenantId(tenantId)
                .syncDate(LocalDateTime.now()).build());
    }


    private void syncInformationResult(Long tenantId, UUID id, JsonNode resultNode) {
        this.sendEntity(RabbitKeys.INFORMATION_SYNC_QUEUE_KEY, ResultMsg.builder()
                .requestId(id).action("Contracts")
                .entity(resultNode).tenantId(tenantId)
                .syncDate(LocalDateTime.now()).build());
    }

    private Flux<JsonNode> entityInformation(ClientProperties properties) {
        return super.autoTaskClient.get(ClientUtils.builderRequestUrl(properties.getBaseUrl(),
                "/V1.0/Contracts/entityInformation/fields"))
                .subscriberContext(ctx -> ctx.put("properties", properties))
                .flatMapMany(jsonNode -> Flux.fromIterable(jsonNode.withArray("fields")));
    }
}
